package org.example.maven.utils;

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.*;

public class AliyunUtils {
    private static final String BUCKET_NAME = "masterjiuyou";
    private static final String ENDPOINT = "https://oss-cn-hangzhou.aliyuncs.com";
    private static final String REGION = "cn-hangzhou";
    // 创建线程池，根据实际情况调整线程数
    private static final ExecutorService executor = Executors.newFixedThreadPool(10);
    private static final OSS ossClientExcel; // 共享客户端
    static {
        // 初始化OSS客户端（整个应用生命周期内共享）
        ClientBuilderConfiguration config = new ClientBuilderConfiguration();
        config.setSignatureVersion(SignVersion.V4);
        try {
            ossClientExcel = OSSClientBuilder.create()
                    .endpoint(ENDPOINT)
                    .credentialsProvider(CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider())
                    .clientConfiguration(config)
                    .region(REGION)
                    .build();
        } catch (com.aliyuncs.exceptions.ClientException e) {
            throw new RuntimeException(e);
        }
    }

    public static String uploadFile(MultipartFile file) throws Exception {
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        System.out.println(credentialsProvider);

        // 创建OSSClient实例。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(ENDPOINT)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(REGION)
                .build();
        try(InputStream inputStream = file.getInputStream()) {
            String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            String objectName = UUID.randomUUID().toString().replaceAll("-", "")+suffix;
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, objectName, inputStream);
            // 如果需要上传时设置存储类型和访问权限，请参考以下示例代码。
            // ObjectMetadata metadata = new ObjectMetadata();
            // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
            // metadata.setObjectAcl(CannedAccessControlList.Private);
            // putObjectRequest.setMetadata(metadata);

            // 上传文件。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            return "https://"+BUCKET_NAME+"."+ENDPOINT.substring(ENDPOINT.lastIndexOf("/")+1)+"/"+objectName;
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
            return null;
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
            return null;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
    // 异步上传方法
    public static CompletableFuture<String> asyncUpload(String fileName) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                String url = uploadSingleImage(ossClientExcel, fileName);
                if (url == null) {
                    throw new CompletionException(new RuntimeException("上传返回空URL"));
                }
                return url;
            } catch (Exception e) {
                throw new CompletionException(e);
            }
        }, executor);
    }

    private static String uploadSingleImage(OSS ossClient, String originalFileName) {
        String fileExtension = "";
        int dotIndex = originalFileName.lastIndexOf(".");
        if (dotIndex > 0) {
            fileExtension = originalFileName.substring(dotIndex);
        }

        String uuidFileName = UUID.randomUUID().toString().replaceAll("-", "") + fileExtension;
        String localImagePath = "D:\\ideawork\\images\\images\\" + originalFileName;

        File imageFile = new File(localImagePath);
        if (!imageFile.exists()) {
            System.err.println("File not found: " + localImagePath);
            return null;
        }

        try (InputStream inputStream = new FileInputStream(imageFile)) {
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType(getContentType(fileExtension));
            PutObjectRequest request = new PutObjectRequest(BUCKET_NAME, uuidFileName, inputStream, metadata);

            ossClient.putObject(request);

            // 预先生成URL基地址
            String urlBase = "https://" + BUCKET_NAME + "."
                    + ENDPOINT.substring(ENDPOINT.lastIndexOf("/") + 1) + "/";
            return urlBase + uuidFileName;

        } catch (IOException e) {
            System.err.println("IO Error with file: " + originalFileName);
            e.printStackTrace();
            return null;
        } catch (Exception e) {
            System.err.println("Upload failed for: " + originalFileName);
            e.printStackTrace();
            return null;
        }
    }

    // 获取常见图片的MIME类型
    private static String getContentType(String fileExtension) {
        switch (fileExtension.toLowerCase()) {
            case ".jpg":
            case ".jpeg":
                return "image/jpeg";
            case ".png":
                return "image/png";
            case ".gif":
                return "image/gif";
            case ".bmp":
                return "image/bmp";
            default:
                return "application/octet-stream";
        }
    }
}
